﻿//  Copyright (c) 2010 Ray Liang (http://www.dotnetage.com)
//  Dual licensed under the MIT and GPL licenses:
//  http://www.opensource.org/licenses/mit-license.php
//  http://www.gnu.org/licenses/gpl.html

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web.Mvc;
using System.Web.UI;
using System.Xml;


namespace DNA.Mvc.jQuery
{
    public abstract class jQueryHierarchicalComponentBuilder<TOptions, TComponent, TNode, TFactory, TBuilder> : jQueryComponentBuilder<TOptions, TComponent, TBuilder>
        where TNode : NavigableView, IComponentItemContainer<TNode>
        where TComponent : DataBindableComponentContainer<TNode>
        where TBuilder : jQueryHierarchicalComponentBuilder<TOptions, TComponent, TNode, TFactory, TBuilder>
    {
        public jQueryHierarchicalComponentBuilder(TComponent component, ViewContext viewContext, IViewDataContainer viewContainer) : base(component, viewContext, viewContainer) { }
        
        /// <summary>
        /// Add node items.
        /// </summary>
        /// <param name="items"></param>
        /// <returns></returns>
        public TBuilder Items(Action<TFactory> items)
        {
            if (items != null)
                items.Invoke(CreateNodeItemFactory());
            return this as TBuilder;
        }

        protected abstract TFactory CreateNodeItemFactory();

        protected abstract HierarchialBindingFactory<TNode, TComponent> CreateBindingFactory();

        [Obsolete]
        public TBuilder ItemDataBound(Action<TNode> item)
        {
            Component.ItemDataBoundTemplate = item;
            return this as TBuilder;
        }

        private HierarchialBindingFactory<TNode, TComponent> Factory
        {
            get
            {
                return CreateBindingFactory();
            }
        }

        public TBuilder Bind<T>(IHierarchicalEnumerable model, MapAction<T, NavigatableNode> mapper)
        {
            Factory.Bind<T>(model, mapper);
            return this as TBuilder;
        }

        public TBuilder Bind(HierarchicalNodeProviderBase dataProvider)
        {
            return this.Bind(dataProvider, true);
        }

        public virtual TBuilder Bind(HierarchicalNodeProviderBase dataProvider,bool showRoot)
            //where T : HierarchicalNode
        {
            Factory.Bind(dataProvider,showRoot);
            return this as TBuilder;
        }

        public virtual TBuilder Bind<T>(T root)
             where T : HierarchicalNode
        {
            Factory.Bind<T>(root, null,true);
            return this as TBuilder;
        }

        public TBuilder Bind<T>(T root, Func<T, bool> dataBound)
             where T : HierarchicalNode
        {
            Factory.Bind<T>(root, dataBound, true);
            return this as TBuilder;
        }

        public TBuilder Bind<T>(T root, Func<T, bool> dataBound,bool showRoot)
             where T : HierarchicalNode
        {
            Factory.Bind<T>(root, dataBound,showRoot);
            return this as TBuilder;
        }

        public virtual TBuilder Bind(string xmlUrl,bool showRoot)
        {
            Factory.BindXml(xmlUrl,showRoot);
            return this as TBuilder;
        }

        public TBuilder Bind(string xmlUrl, MapAction<XmlNode, HierarchicalNode> mapper,bool showRoot)
        {
            Factory.BindXml(xmlUrl, mapper,showRoot);
            return this as TBuilder;
        }

        public TBuilder BindSiteMap(string siteMapUrl)
        {
            Factory.BindSiteMap(siteMapUrl);
            return this as TBuilder;
        }

        public TBuilder BindSiteMap(string siteMapUrl, string selectPath)
        {
            Factory.BindSiteMap(siteMapUrl, selectPath);
            return this as TBuilder;
        }
    }

    //public abstract class jQueryHierarchicalComponentBuilderBase<TOption, TContainer,TFactory, TBuilder> : jQueryComponentBuilder<TOption, TContainer, TBuilder>
    //    where TBuilder : jQueryHierarchicalComponentBuilderBase<TOption, TContainer, TFactory, TBuilder>
    //{
    //    protected abstract TFactory CreateNodeItemFactory();

    //    /// <summary>
    //    /// Add node items.
    //    /// </summary>
    //    /// <param name="items"></param>
    //    /// <returns></returns>
    //    public TBuilder Items(Action<TFactory> items)
    //    {
    //        if (items != null)
    //            items.Invoke(CreateNodeItemFactory());
    //        return this as TBuilder;
    //    }

    //    public TBuilder NodeTemplate<TModel>(Action<TModel> template)
    //        where TModel:IHierarchyData
    //    {
    //        return this as TBuilder;
    //    }
        
    //    public TBuilder NodeTemplate<TModel>(Func<TModel,object> template)
    //where TModel : IHierarchyData
    //    {
    //        return this as TBuilder;
    //    }

    //    public TBuilder Bind<TModel>(TModel model)
    //        where TModel:IHierarchyData
    //    {
    //        return this as TBuilder;
    //    }

    //    public TBuilder Bind<TModel>(TModel model)
    //        where TModel : IHierarchicalEnumerable
    //    {
    //        //model.GetHierarchyData(null).
    //        return this as TBuilder;
    //    }

    //    public TBuilder BindSiteMap()
    //    {
    //        return this as TBuilder;
    //    }

    //    public TBuilder BindXml(string url)
    //    {
    //        return this as TBuilder;
    //    }

    //    protected abstract TNode OnNodeCreated(IHierarchyData model);

    //    public override void Render()
    //    {
    //        base.Render();
    //    }
    //}
}
